<?php

namespace App\Dao;

use App\Model\Anchor;
use App\Model\UserCardPack;
use App\Utils\MemcacheClient;
use Hyperf\Context\ApplicationContext;
use Hyperf\DbConnection\Db;

class AnchorDao
{
    private static $instance;

    public static function getInstance()
    {
        if (!self::$instance) {
            self::$instance = Applicationcontext::getcontainer()->get(self::class);
        }
        return self::$instance;
    }


    // 获取主播信息，包含主播型用户信息
    public function findAnchorInfoCache($uid)
    {
        $instance = MemcacheClient::getInstance();
        $cache = $instance->get('anchor_info_' . $uid);
        if ($cache === false) {
            $cache = $this->findAnchorInfoById($uid);
            $instance->set('anchor_info_' . $uid, $cache, 300);
        }
        return $cache;
    }


    public function findAnchorInfoById($uid)
    {
        return Anchor::query()->join('tb_user', 'tb_user.id', '=', 'tb_anchor.uid')
            ->where('tb_anchor.uid', $uid)
            ->select('tb_anchor.*', 'tb_user.nickname', 'tb_user.head_image', 'tb_user.sex', 'tb_user.head_image_status', 'tb_user.gift_count', 'tb_user.integral', 'tb_user.level', 'tb_user.phone', 'tb_user.weixin', 'tb_user.qq', 'tb_user.phone_show', 'tb_user.is_faceAuth')
            ->first();
    }


    /**
     * Note - 增加主播的接通人数、通话时长
     * DateTime 2024/8/2 11:37
     * User Admin
     * @param $anchor_id
     * @param $time
     * @return int
     */
    public function addAnchorTime($anchor_id, $time)
    {
        // $sql = "update {$this->tableA} set connection_time = connection_time + ?,connection_num=connection_num+? where uid = ?";
        // $pd = $this->createCommand($sql);
        // $pd->execute(array($time, 1, $anchor_id));
        // return $pd->rowCount();
        return Anchor::query()->where('uid', $anchor_id)->update([
            'connection_time' => DB::raw('connection_time + ' . $time),
            'connection_num' => DB::raw('connection_num + 1'),
        ]);
    }


    /**
     * 获取推荐主播
     * @param $current_uid_list
     * @param $is_need
     * @return mixed
     */
    public function recommendList($current_uid_list, $is_need)
    {
        $data = Anchor::query()->join('tb_user', 'tb_user.id', '=', 'tb_anchor.uid')
            // ->select('tb_user.id', 'tb_user.nickname', 'tb_user.head_image', 'tb_user.signature', 'u.head_image_status', 'tb_user.age', 'tb_user.province', 'tb_user.city', 'tb_user.ext', 'tb_user.noble', 'tb_user.user_type', 'tb_user.sex', 'tb_user.level')
            ->select('tb_user.id', 'tb_user.nickname', 'tb_user.head_image', 'tb_user.signature', 'tb_user.head_image_status', 'tb_user.age', 'tb_user.province', 'tb_user.city', 'tb_user.ext', 'tb_user.noble', 'tb_user.user_type', 'tb_user.sex', 'tb_user.level', DB::raw('(UNIX_TIMESTAMP() - ROUND((RAND() * 86400 ))) AS time')) // 86400 秒是一天的秒数（大约）
            ->where('tb_anchor.status', 0)
            ->where('tb_user.head_image_status', 3)
            ->where('recommend', 1)
            ->when(!empty($current_uid_list), function ($query) use ($current_uid_list) {
                return $query->whereNotIn('tb_anchor.uid', $current_uid_list);
            })
            ->orderBy('recommend', 'desc')
            ->orderBy('star_rank', 'desc')
            ->limit($is_need)
            ->get();
        return $data->toArray();
    }


    /**
     * 随机获取一个推荐主播
     * @param array $notUids
     * @return array
     */
    public function getRecommendAnchorOne(array $notUids = [])
    {
        $data = Anchor::query()->from('tb_anchor AS a')
            ->join('tb_user AS u', 'u.id', '=', 'a.uid')
            ->select(['u.id', 'u.nickname', 'u.head_image', 'u.age', 'u.sex', 'u.height', 'u.province', 'u.city', 'u.ext', 'u.signature', 'u.register_ip', 'u.lng', 'u.lat', 'a.video_price', 'a.audio_price', 'a.greet_price'])
            ->where('a.status', 0)
            ->where('u.status', 0)
            ->where('u.isdel', 0)
            ->where('u.online', '>', 0)
            // ->where('a.recommend', 1)
            ->when(!empty($notUids), function ($query) use ($notUids) {
                return $query->whereNotIn('a.uid', $notUids);
            })
            ->inRandomOrder()
            ->first();
        $data = modelToArray($data);
        if (!empty($data)) {
            $ext = json_decode($data['ext'], true);
            $data['birthday'] = $ext['birthday'] ?? '';
            $data['constellation'] = $ext['constellation'] ?? '';
            $data['job'] = $ext['job'] ?? '';
        }
        return $data;


//         if(!empty($notUids)){
//             $where .= " and a.uid not in ($notUids) ";
//         }
//
//         $sql = "select u.id,u.nickname,u.head_image,u.age,u.sex,u.height,u.province,u.city,u.ext,u.signature,u.register_ip,u.lng,u.lat,a.video_price,a.audio_price,a.greet_price from tb_anchor a
// inner join tb_user u on a.uid=u.id where u.isdel = 0 and
// a.status = 0 and u.status=0 and u.is_faceAuth in (1,3) and u.online>0" . $where . " order by rand() limit 0,1";
//         $pd = $this->createCommand($sql);
//         $pd->execute(array(0));
//         $data = $pd->fetch(PDO::FETCH_ASSOC);
//
//
//         if(!empty($data)){
//             $ext=json_decode($data['ext'],true);
//             $data['birthday']=$ext['birthday'];
//             $data['constellation']=$ext['constellation'];
//             $data['job']=$ext['job'];
//         }
//         return $data;
    }


    /**
     * Note - 获取一键打招呼用户列表
     * DateTime 2024/8/15 10:22
     * User Admin
     * @param $uid
     * @param int $limit
     * @return array
     */
    public function getBatchGreetAnchor($uid, int $limit = 6)
    {
//         $where = " and a.uid not in (select user_id from tb_user_tease where uid={$uid})";
//         $where .= " and u.sex=2 and u.channel != 'xy_oppo' and u.channel!='xy_vivo' and u.channel!='xy_bd' and json_extract(u.ext2, '$.channel') not in ('xy_oppo','xy_vivo','xy_bd')";
//         $sql = "select u.id,u.nickname,u.head_image,u.head_image_status,u.sex,u.province,u.city from tb_anchor a
// inner join tb_user u on a.uid=u.id where u.isdel = 0 and
// a.status = 0 and u.status=0 and u.is_faceAuth in (1,3) and a.is_inside=1" . $where . " order by rand() limit 0,6";
        // $pd = $this->createCommand($sql);
        // $pd->execute(array(0));
        // $data = $pd->fetchAll(PDO::FETCH_ASSOC);
        // return $data;
        return Anchor::query()->from('tb_anchor AS a')->join('tb_user AS u', 'u.id', '=', 'a.uid')
            ->select(['u.id', 'u.nickname', 'u.head_image', 'u.head_image_status', 'u.sex', 'u.province', 'u.city'])
            ->where('u.isdel', 0)
            ->where('a.status', 0)
            ->where('u.status', 0)
            ->where('a.is_inside', 1)
            ->where('u.sex', 2)
            ->whereNotIn('u.channel', ['xy_oppo', 'xy_vivo', 'xy_bd'])
            ->whereNotIn(DB::raw("json_extract(u.ext2, '$.channel')"), ['xy_oppo', 'xy_vivo', 'xy_bd'])
            ->whereNotIn('a.uid', function ($query) use ($uid) {
                $query->select('user_id')->from('tb_user_tease')->where('uid', $uid);
            })
            ->orderByRaw('RAND()')
            ->take($limit)
            ->get()->toArray();

    }


    /**
     * Note - 获取免费女用户
     * DateTime 2024/8/15 10:22
     * User Admin
     * @param $refuse_list
     * @param int $first_level
     * @param int $call_type
     * @param int $can_use_card
     * @return array
     */
    public function getFreeFemaleCallUids($refuse_list, $first_level = 0, $call_type = 1, $can_use_card = 0)
    {
        if ($call_type == 1) {
            $accept_type = 'u.accept_video';
        } else {
            $accept_type = 'u.accept_audio';
        }

        if ($can_use_card) {
            $times = strtotime(date("Ymd"));
            $cardCount = CommonSettingDao::getValue('woman_card_count', 10);    // 女用户体验卡上限
            // $anchorCardCountData = $this->query("select c.uid,count(c.id) today_card from tb_user_card_pack c left join tb_user u on c.uid=u.id where u.sex=2 and c.card_type=1 and u.`online`=1 and u.is_faceAuth in (1,3) and get_time>{$times} group by c.uid having today_card>={$cardCount}");
            $anchorCardCountData = UserCardPack::query()->from('tb_user_card_pack AS c')->leftJoin('tb_user AS u', 'c.uid', '=', 'u.id')
                ->selectRaw("c.uid,count(c.id) today_card")
                ->where('u.sex', 2)
                ->where('c.card_type', 1)
                ->where('u.online', 1)
                ->where('get_time', '>', $times)
                ->groupBy('c.uid')
                ->havingRaw("today_card>={$cardCount}")
                ->get()
                ->pluck('uid')
                ->toArray();

            $anchorCardCount = '';
            if (!empty($anchorCardCountData)) {
                $anchorCardCount = implode(",", $anchorCardCountData);
            }

            // $sql = "SELECT a.uid,a.video_price,a.audio_price,a.video_url as call_video,a.accept_audio,u.accept_video,u.head_image,u.nickname,u.sex,u.`level`,u.province,u.city,case when find_in_set(a.uid,'{$anchorCardCount}') then 1 else 0 end order_card FROM {$this->table} a INNER JOIN {$this->tableU} u ON a.uid=u.id WHERE u.sex = ? AND u.`online` = ? AND u.is_faceAuth in (1,3) AND {$accept_type} = ? AND u.`status` = ? AND u.is_disturb = ?{$where} ORDER BY order_card asc,RAND()";
            $result = Anchor::query()->from('tb_anchor AS a')->leftJoin('tb_user AS u', 'a.uid', '=', 'u.id')
                ->selectRaw("a.uid,a.video_price,a.audio_price,a.video_url as call_video,a.accept_audio,u.accept_video,u.head_image,u.nickname,u.sex,u.level,u.province,u.city,case when find_in_set(a.uid,'{$anchorCardCount}') then 1 else 0 end order_card")
                ->where('u.sex', 2)
                ->where('u.online', 1)
                ->where($accept_type, 1)
                ->where('u.status', 0)
                ->where('u.is_disturb', 0)
                ->when(!empty($refuse_list), function ($query) use ($refuse_list) {
                    return $query->whereNotIn('id', $refuse_list);
                })
                ->when($first_level > 0, function ($query) use ($first_level) {
                    return $query->where('a.first_level', $first_level);
                })
                ->orderByRaw('order_card asc,RAND()')
                ->get()->toArray();

        } else {
            // $sql = "SELECT a.uid,a.video_price,a.audio_price,a.video_url as call_video,a.accept_audio,u.accept_video,u.head_image,u.nickname,u.sex,u.`level`,u.province,u.city FROM {$this->table} a INNER JOIN {$this->tableU} u ON a.uid=u.id WHERE u.sex = ? AND u.`online` = ? AND u.is_faceAuth in (1,3) AND {$accept_type} = ? AND u.`status` = ? AND u.is_disturb = ?{$where} ORDER BY RAND()";
            // $bindVal = [2, 1, 1, 0, 0];
            $result = Anchor::query()->from('tb_anchor AS a')->leftJoin('tb_user AS u', 'a.uid', '=', 'u.id')
                ->selectRaw("a.uid,a.video_price,a.audio_price,a.video_url as call_video,a.accept_audio,u.accept_video,u.head_image,u.nickname,u.sex,u.level,u.province,u.city")
                ->where('u.sex', 2)
                ->where('u.online', 1)
                ->where($accept_type, 1)
                ->where('u.status', 0)
                ->where('u.is_disturb', 0)
                ->when(!empty($refuse_list), function ($query) use ($refuse_list) {
                    return $query->whereNotIn('id', $refuse_list);
                })
                ->when($first_level > 0, function ($query) use ($first_level) {
                    return $query->where('a.first_level', $first_level);
                })
                ->orderByRaw('RAND()')
                ->get()->toArray();
        }

        // $pd = $this->createCommand($sql);
        // $pd->execute($bindVal);
        // $result = $pd->fetchAll(PDO::FETCH_ASSOC);
        $uids = [];
        $list = [];
        foreach ($result as $k => $v) {
            $uids[] = $v['uid'];
            $list[$v['uid']] = $v;
        }
        return [$uids, $list];
    }


    /**
     * 获取固定名单女用户
     * @param int $isOnline
     * @param int $isInside
     * @param int $isInsideS
     * @param int $limitNum
     * @param array $notIn
     * @return array
     */
    public function getFemaleUids($isOnline = 0, $isInsideS = 0, $isInside = 0, $limitNum = 0, $notIn = [], $payNotifyPrivilege = 0)
    {
        $where = "u.sex=? AND u.is_faceAuth in (1,3) AND u.isdel=? AND u.status=?";
        $bindVal = [2, 0, 0];
        $orderBy = " u.online DESC,u.login_time DESC";
        if ($isOnline) {
            $where .= " AND u.online=?";
            $bindVal[] = 1;
        }
        if ($isInsideS) {
            $where .= " AND a.is_insideS=?";
            $bindVal[] = 1;
        }
        if ($isInside) {
            $where .= " AND a.is_inside=?";
            $bindVal[] = 1;
        }
        if ($payNotifyPrivilege) {
            $where .= " AND a.privilege_pay_notify=?";
            $bindVal[] = 1;
        }
        if (sizeof($notIn) > 0) {
            $where .= sprintf(" AND a.uid NOT IN (%s)", implode(',', $notIn));
        }
        if ($limitNum) {
            $limit = sprintf(" LIMIT %d", $limitNum);
        } else {
            $limit = '';
        }

        $sql = "SELECT a.uid FROM {$this->table} a INNER JOIN tb_user u ON u.id=a.uid WHERE {$where} ORDER BY{$orderBy}{$limit}";
        $pd = $this->createCommand($sql);
        $pd->execute($bindVal);
        $rs = $pd->fetchAll(PDO::FETCH_ASSOC);
        if (!$rs) {
            $rs = [];
        } else {
            $rs = array_column($rs, "uid");
        }
        return $rs;
    }


}